package com.mes.cloud.service;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.mes.cloud.api.dto.request.product.*;
import com.mes.cloud.api.dto.response.product.ProductCustomerDto;
import com.mes.cloud.api.dto.response.product.ProductDetailsDto;
import com.mes.cloud.api.dto.response.product.ProductDto;
import com.mes.cloud.exception.BaseException;
import com.mes.cloud.common.CommPager;
import com.mes.cloud.common.JsonResult;
import com.mes.cloud.constant.Constants;
import com.mes.cloud.dao.ProductBrandDao;
import com.mes.cloud.dao.ProductDao;
import com.mes.cloud.dao.ProductDirectoryDao;
import com.mes.cloud.entity.Product;
import com.mes.cloud.entity.ProductBrand;
import com.mes.cloud.entity.ProductLog;
import com.mes.cloud.entity.vo.ProductDirectoryVo;
import com.mes.cloud.entity.vo.product.CustomerProductVo;
import com.mes.cloud.entity.vo.product.ProductDetailsVo;
import com.mes.cloud.enums.HttpStatusEnum;
import com.mes.cloud.util.DateUtil;
import com.mes.cloud.util.UserUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 产品
 *
 * @author xy
 * @version 2019-08-20 14:30:12
 * @email yuan.xue3@pactera.com
 */
@Service
public class ProductService {

    private ProductDao productDao;

    private IPKeyGenerator ipKeyGenerator;

    private SysCodeGeneratorService sysCodeGeneratorService;

    private LogService logService;

    private ProductDirectoryService productDirectoryService;

    private ProductBrandDao productBrandDao;

    private ProductDirectoryDao productDirectoryDao;

    @SuppressWarnings("SpringJavaAutowiringInspection")
    @Autowired
    public ProductService(ProductDao productDao
            , IPKeyGenerator ipKeyGenerator
            , SysCodeGeneratorService sysCodeGeneratorService
            , LogService logService
            , ProductDirectoryService productDirectoryService
            , ProductBrandDao productBrandDao
            , ProductDirectoryDao productDirectoryDao) {
        this.productDao = productDao;
        this.ipKeyGenerator = ipKeyGenerator;
        this.sysCodeGeneratorService = sysCodeGeneratorService;
        this.logService = logService;
        this.productDirectoryService = productDirectoryService;
        this.productBrandDao = productBrandDao;
        this.productDirectoryDao = productDirectoryDao;
    }

    /**
     * 分页查列表
     *
     * @param pageRequest
     * @return JsonResult
     */
    public JsonResult<CommPager<ProductDto>> pageList(ProductPageRequest pageRequest) {
        //根据产品目录ID，要查询目录下级所有的产品。此处要根据前端的传过来的目录ID，查找下级所有的挂产品的目录ID
        String sonIds = "";
        if (!StringUtils.isEmpty(pageRequest.getProductDirectoryId())) {
            List<ProductDirectoryVo> sonDirectoryList = productDirectoryDao.selectLastSonList(pageRequest.getProductDirectoryId());
            if (!CollectionUtils.isEmpty(sonDirectoryList)) {
                //从list中拼接ID
                List<String> sonIdList = sonDirectoryList.stream().map(ProductDirectoryVo::getId).collect(Collectors.toList());
                sonIds = String.join(",", sonIdList);
            }
        }
        if (!StringUtils.isEmpty(sonIds)) {
            pageRequest.setProductDirectoryId(sonIds);
        }

        Page<ProductDto> page = PageHelper.startPage(pageRequest.getCurrentPage(), pageRequest.getPageSize());
        //查询条件
        List<Product> productList = productDao.pageList(pageRequest);

        List<ProductDto> productDtoList = new ArrayList<>();
        for (Product product : productList) {
            ProductDto productDto = new ProductDto();
            BeanUtils.copyProperties(product, productDto);
            productDtoList.add(productDto);
        }

        CommPager<ProductDto> pageResult = new CommPager<>(page, productDtoList);
        JsonResult<CommPager<ProductDto>> jsonResult = new JsonResult<>();
        jsonResult.setMsg(HttpStatusEnum.OK.getMessage()).setCode(HttpStatusEnum.OK.getCode()).setData(pageResult);

        return jsonResult;
    }

    /**
     * @Author ysd
     * @Description <可售产品_列表查询>
     * @Date 17:44 2019/9/24
     **/
    public JsonResult<CommPager<ProductCustomerDto>> productCustomerPageList(ProductCustomerPageRequest pageRequest) {
        Page<ProductDto> page = PageHelper.startPage(pageRequest.getCurrentPage(), pageRequest.getPageSize());
        //查询条件
        List<CustomerProductVo> productList = productDao.productCustomerPageList(pageRequest);

        List<ProductCustomerDto> productDtoList = new ArrayList<>();
        for (CustomerProductVo product : productList) {
            ProductCustomerDto productDto = new ProductCustomerDto();
            BeanUtils.copyProperties(product, productDto);
            productDtoList.add(productDto);
        }
        CommPager<ProductCustomerDto> pageResult = new CommPager<>(page, productDtoList);
        JsonResult<CommPager<ProductCustomerDto>> jsonResult = new JsonResult<>();
        jsonResult.setMsg(HttpStatusEnum.OK.getMessage()).setCode(HttpStatusEnum.OK.getCode()).setData(pageResult);
        return jsonResult;
    }

    /**
     * 查询列表
     *
     * @param productRequest
     * @return JsonResult
     */
    public JsonResult<List<ProductDto>> list(ProductRequest productRequest) {
        //查询条件
        Product selectParam = new Product();
        BeanUtils.copyProperties(productRequest, selectParam);
        List<Product> productList = productDao.select(selectParam);

        List<ProductDto> productDtoList = new ArrayList<>();
        for (Product product : productList) {
            ProductDto productDto = new ProductDto();
            BeanUtils.copyProperties(product, productDto);
            productDtoList.add(productDto);
        }

        JsonResult<List<ProductDto>> jsonResult = new JsonResult<>();
        jsonResult.setMsg(HttpStatusEnum.OK.getMessage()).setCode(HttpStatusEnum.OK.getCode()).setData(productDtoList);

        return jsonResult;
    }

    /**
     * 新增
     *
     * @param productRequest
     * @return JsonResult
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult add(ProductAddRequest productRequest) {
        JsonResult jsonResult = new JsonResult();
        //目录类型只能选择竞品目录
        if (!Constants.DIRECTORY_TYPE_COMPETE.equals(productRequest.getProductDirectoryType())) {
            jsonResult.setMsg(HttpStatusEnum.PRODUCT_DIRECTORY_TYPE_ERROR.getMessage());
            jsonResult.setCode(HttpStatusEnum.PRODUCT_DIRECTORY_TYPE_ERROR.getCode());
            return jsonResult;
        }

        //产品名称校验 已存在不允许添加
        Product product = new Product();
        product.setName(productRequest.getName());
        int productCount = productDao.selectCount(product);
        if (productCount > 0) {
            jsonResult.setMsg(HttpStatusEnum.PRODUCT_EXIST.getMessage());
            jsonResult.setCode(HttpStatusEnum.PRODUCT_EXIST.getCode());
            return jsonResult;
        }

        //必须是竞品目录的最后一个节点才能新增产品
        ProductDirectoryRequest productDirectoryRequest = new ProductDirectoryRequest();
        productDirectoryRequest.setParentId(productRequest.getProductDirectoryId());
        int count = productDirectoryService.getCount(productDirectoryRequest);
        //根据parentId查询,如果返回结果大于0,存在子节点
        if (count > 0) {
            jsonResult.setMsg(HttpStatusEnum.PRODUCT_DIRECTORY_EXIST_CHILD_NODE.getMessage());
            jsonResult.setCode(HttpStatusEnum.PRODUCT_DIRECTORY_EXIST_CHILD_NODE.getCode());
            return jsonResult;
        }

        BeanUtils.copyProperties(productRequest, product);

        //生成产品code 品牌code+8位数字
        if (StringUtils.isNotEmpty(productRequest.getBrandId())) {
            // 根据品牌ID查找品牌具体信息
            ProductBrand productBrand = productBrandDao.selectByPrimaryKey(productRequest.getBrandId());
            String code = sysCodeGeneratorService.getCode(Constants.CODE_GENERATOR_PRODUCT);
            product.setCode(productBrand.getAbbreviationName() + code);
        }

        //添加的都是竞品
        product.setType(Constants.PRODUCT_TYPE_COMPETE);
        //数据来源(1.sap 2.fsfa 3.crm)
        product.setSource(Constants.SOURCE_CRM);
        product.setId(ipKeyGenerator.getGenerateKey());
        product.setUpdateDateStr(DateUtil.updateDateStr());
        product.setCreateBy(UserUtil.getCreateByName());
        product.setUpdateBy(UserUtil.getUpdateByName());
        product.setCreateByNo(UserUtil.getCreateByNo());
        product.setUpdateByNo(UserUtil.getUpdateByNo());

        count = productDao.insertSelective(product);
        if (count > 0) {
            this.insertLog(product.getId(), Constants.ADD_PRODUCT);
            jsonResult.setMsg(HttpStatusEnum.OK.getMessage()).setCode(HttpStatusEnum.OK.getCode());
        } else {
            throw new BaseException(HttpStatusEnum.FAIL.getCode(),HttpStatusEnum.FAIL.getMessage());
        }

        return jsonResult;
    }

    /**
     * 更新
     *
     * @param productUpdateRequest
     * @return JsonResult
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult update(ProductUpdateRequest productUpdateRequest) {
        JsonResult jsonResult = new JsonResult();
        //目录类型只能选择竞品目录
//        if (!productUpdateRequest.getProductDirectoryType().equals(Constants.DIRECTORY_TYPE_COMPETE)) {
//            jsonResult.setMsg(HttpStatusEnum.PRODUCT_DIRECTORY_TYPE_ERROR.getMessage());
//            jsonResult.setCode(HttpStatusEnum.PRODUCT_DIRECTORY_TYPE_ERROR.getCode());
//            return jsonResult;
//        }
        //产品名称校验，已存在不允许添加
        Product dbProduct = productDao.selectByPrimaryKey(productUpdateRequest.getId());
        if (Objects.nonNull(dbProduct)) {
            String name = dbProduct.getName();
            //名称发生变动
            if (!name.equals(productUpdateRequest.getName())) {
                //检查变更的名称是否存在
                //产品名称校验 已存在不允许添加
                Product product = new Product();
                product.setName(productUpdateRequest.getName());
                int productCount = productDao.selectCount(product);
                if (productCount > 0) {
                    jsonResult.setMsg(HttpStatusEnum.PRODUCT_EXIST.getMessage());
                    jsonResult.setCode(HttpStatusEnum.PRODUCT_EXIST.getCode());
                    return jsonResult;
                }
            }
        }

        //必须是竞品目录的最后一个节点才能新增产品
        ProductDirectoryRequest productDirectoryRequest = new ProductDirectoryRequest();
        productDirectoryRequest.setParentId(productUpdateRequest.getProductDirectoryId());
        int count = productDirectoryService.getCount(productDirectoryRequest);

        //根据parentId查询,如果返回结果大于0,存在子节点
        if (count > 0) {
            jsonResult.setMsg(HttpStatusEnum.PRODUCT_DIRECTORY_EXIST_CHILD_NODE.getMessage());
            jsonResult.setCode(HttpStatusEnum.PRODUCT_DIRECTORY_EXIST_CHILD_NODE.getCode());
            return jsonResult;
        }

        Product product = new Product();
        BeanUtils.copyProperties(productUpdateRequest, product);
        product.setUpdateDateStr(DateUtil.updateDateStr());
        product.setUpdateBy(UserUtil.getUpdateByName());
        product.setUpdateByNo(UserUtil.getUpdateByNo());

        count = productDao.updateByPrimaryKeySelective(product);
        if (count > 0) {
            this.insertLog(product.getId(), Constants.UPDATE_PRODUCT);
            jsonResult.setMsg(HttpStatusEnum.OK.getMessage());
            jsonResult.setCode(HttpStatusEnum.OK.getCode());
        } else {
            throw new BaseException(HttpStatusEnum.FAIL.getCode(),HttpStatusEnum.FAIL.getMessage());
        }
        return jsonResult;
    }


    /**
     * 查看详情
     *
     * @param id
     * @return JsonResult
     */
    @SuppressWarnings("unchecked")
    public JsonResult<ProductDetailsDto> get(String id) {
        JsonResult jsonResult = new JsonResult();

        ProductDetailsVo productDetailsVo = productDao.selectProductDetails(id);
        if (Objects.isNull(productDetailsVo)) {
            return jsonResult.setCode(HttpStatusEnum.RECORD_NOT_EXIST.getCode()).setMsg(HttpStatusEnum.RECORD_NOT_EXIST.getMessage());
        }

        ProductDetailsDto productDetailsDto = new ProductDetailsDto();
        BeanUtils.copyProperties(productDetailsVo, productDetailsDto);

        return jsonResult.setMsg(HttpStatusEnum.OK.getMessage()).setCode(HttpStatusEnum.OK.getCode()).setData(productDetailsDto);
    }

    /**
     * 禁用启用
     *
     * @param productEnableRequest
     * @return JsonResult
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult updateEnableFlag(ProductEnableRequest productEnableRequest) {
        JsonResult jsonResult = new JsonResult();
        //只允许修改竞品状态
        for (String str : productEnableRequest.getTypes()) {
            //如果非竞品
            if (!str.equals(Constants.PRODUCT_TYPE_COMPETE)) {
                jsonResult.setMsg(HttpStatusEnum.PRODUCT_ENABLE_ERROR.getMessage());
                jsonResult.setCode(HttpStatusEnum.PRODUCT_ENABLE_ERROR.getCode());
                return jsonResult;
            }
        }

        productEnableRequest.setUpdateDateStr(DateUtil.updateDateStr());
        productEnableRequest.setUpdateBy(UserUtil.getUpdateByName());
        productEnableRequest.setUpdateByNo(UserUtil.getUpdateByNo());

        int count = productDao.batchUpdateEnable(productEnableRequest);
        if (count > 0) {
            String flag = Constants.ENABLE_PRODUCT;
            if (Constants.ENABLE_FLAG_NO.equals(productEnableRequest.getEnableFlag())) {
                flag = Constants.DISABLE_PRODUCT;
            }
            // 插入操作日志
            for (String id : productEnableRequest.getIds()) {
                this.insertLog(id, flag);
            }

            jsonResult.setMsg(HttpStatusEnum.OK.getMessage());
            jsonResult.setCode(HttpStatusEnum.OK.getCode());
        } else {
            throw new BaseException(HttpStatusEnum.FAIL.getCode(),HttpStatusEnum.FAIL.getMessage());
        }

        return jsonResult;
    }

    /**
     * 查列表 对标竞品新增关联产品列表查询
     *
     * @param pageRequest
     * @return JsonResult
     */
    public JsonResult<CommPager<ProductDto>> pageListByType(ProductListPageRequest pageRequest) {

        //根据产品目录ID，要查询目录下级所有的产品。此处要根据前端的传过来的目录ID，查找下级所有的挂产品的目录ID
        String sonIds = "";
        if (!StringUtils.isEmpty(pageRequest.getProductDirectoryId())) {
            List<ProductDirectoryVo> sonDirectoryList = productDirectoryDao.selectLastSonList(pageRequest.getProductDirectoryId());
            if (!CollectionUtils.isEmpty(sonDirectoryList)) {
                //从list中拼接ID
                List<String> sonIdList = sonDirectoryList.stream().map(ProductDirectoryVo::getId).collect(Collectors.toList());
                sonIds = String.join(",", sonIdList);
            }
        }
        if (!StringUtils.isEmpty(sonIds)) {
            pageRequest.setProductDirectoryId(sonIds);
        }

        Page<ProductDto> page = PageHelper.startPage(pageRequest.getCurrentPage(), pageRequest.getPageSize());
        //查询条件
        pageRequest.setEnableFlag(Constants.ENABLE_FLAG_YES);
        //如果是产品类型是竞品查询欣和成品与流通商品,如果产品类型非竞品则查询竞品数据
        List<Product> productList = productDao.pageListByType(pageRequest);

        List<ProductDto> productDtoList = new ArrayList<>();
        for (Product product : productList) {
            ProductDto productDto = new ProductDto();
            BeanUtils.copyProperties(product, productDto);
            productDtoList.add(productDto);
        }

        CommPager<ProductDto> pageResult = new CommPager<>(page, productDtoList);
        JsonResult<CommPager<ProductDto>> jsonResult = new JsonResult<>();
        jsonResult.setMsg(HttpStatusEnum.OK.getMessage()).setCode(HttpStatusEnum.OK.getCode()).setData(pageResult);

        return jsonResult;
    }

    /**
     * <组合、标识产品新增关联产品列表查询>
     *
     * @param productListPageRequest
     * @return com.shinho.tntframe.core.common.model.JsonResult<com.shinho.tntframe.core.common.model.CommPager<com.shinho.crm.base.api.dto.response.product.ProductDto>>
     * @author xy
     * @date 2019/8/23 9:44
     */
    public JsonResult<CommPager<ProductDto>> pageListAndTypeFilter(ProductListPageRequest productListPageRequest) {

        //根据产品目录ID，要查询目录下级所有的产品。此处要根据前端的传过来的目录ID，查找下级所有的挂产品的目录ID
        String sonIds = "";
        if (!StringUtils.isEmpty(productListPageRequest.getProductDirectoryId())) {
            List<ProductDirectoryVo> sonDirectoryList = productDirectoryDao.selectLastSonList(productListPageRequest.getProductDirectoryId());
            if (!CollectionUtils.isEmpty(sonDirectoryList)) {
                //从list中拼接ID
                List<String> sonIdList = sonDirectoryList.stream().map(ProductDirectoryVo::getId).collect(Collectors.toList());
                sonIds = String.join(",", sonIdList);
            }
        }
        if (!StringUtils.isEmpty(sonIds)) {
            productListPageRequest.setProductDirectoryId(sonIds);
        }

        Page<ProductDto> page = PageHelper.startPage(productListPageRequest.getCurrentPage(), productListPageRequest.getPageSize());
        //查询条件
        productListPageRequest.setEnableFlag(Constants.ENABLE_FLAG_YES);
        //如果产品是竞品则查询竞品数据，如果产品类型不是竞品则查询欣和成品与流通商品
        List<Product> productList = productDao.pageListAndTypeFilter(productListPageRequest);

        List<ProductDto> productDtoList = new ArrayList<>();
        for (Product product : productList) {
            ProductDto productDto = new ProductDto();
            BeanUtils.copyProperties(product, productDto);
            productDtoList.add(productDto);
        }

        CommPager<ProductDto> pageResult = new CommPager<>(page, productDtoList);
        JsonResult<CommPager<ProductDto>> jsonResult = new JsonResult<>();
        jsonResult.setMsg(HttpStatusEnum.OK.getMessage()).setCode(HttpStatusEnum.OK.getCode()).setData(pageResult);

        return jsonResult;
    }

    /**
     * <日志>
     *
     * @param id, logMessage
     * @author xy
     * @date 2019/8/30 16:09
     */
    @SuppressWarnings("Duplicates")
    private void insertLog(String id, String logMessage) {
        ProductLog productLog = new ProductLog();
        productLog.setProductId(id);
        productLog.setMenuCode(Constants.PRODUCT_MENU_CODE);
        productLog.setLog(logMessage);
        productLog.setId(ipKeyGenerator.getGenerateKey());
        productLog.setUpdateDateStr(DateUtil.updateDateStr());
        productLog.setCreateBy(UserUtil.getCreateByName());
        productLog.setUpdateBy(UserUtil.getUpdateByName());
        productLog.setCreateByNo(UserUtil.getCreateByNo());
        productLog.setUpdateByNo(UserUtil.getUpdateByNo());
        logService.insertProductLog(productLog);
    }
}
